/**
 * @(#)Server.java
 *
 *
 * @author
 * @version 1.00 2014/2/28
 */
import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Server {

    private InetAddress inetaddress;
    private ServerSocket server;
    private Socket[] client = new Socket[300];
    private String message=null;
    private int connection=0;
    private int passconnection=0;
    private BufferedReader[] line = new BufferedReader[300];
  	private	PrintWriter[] lineout = new PrintWriter[300];
    private JFrame frame;
    private int ConnectionPointer=0;
    private boolean download=false;
    private boolean upload=false;
    private StringTokenizer stringtokenizer;
    private JFileChooser filechoose;
    private String file_info;
    private File file;
    public Server(){
     	try{
            frame = new JFrame("Server");
            System.out.println("initializing..");
            setupServer();
            System.out.println("running acceptClient class...");
    	   new Thread(new acceptClient()).start();
    	}
    	catch (Exception e){
    		System.out.println("Exception "+e);
    	}
    }

    private class acceptClient implements Runnable{

    	public void run() {
    		try{
    		while(true){
    			connection++;
    			client[connection] = server.accept();
    			passconnection = connection;
    			System.out.println("new accepted client no " + connection+"... ");
    			new Thread(new clientHandler()).start();
    			System.out.print(" " +"clienthandler ok  ");
    		}

    		}catch (Exception e){
    			System.out.println("Exception 1, "+e);
    		}
    	}

    }
    private class clientHandler implements Runnable{
	    public void run(){
    		try{

 			int number = passconnection;
 			System.out.println("number " + number);
    		line[number] =
  			    new BufferedReader(new InputStreamReader(client[number].getInputStream()));

  			lineout[number] =
  				new PrintWriter(client[number].getOutputStream(), true);

			  lineout[number].println("Welcome!");

    		while((message=line[number].readLine())!=null){
                message.trim();
                System.out.println("waiting for ConnectionPointer..");
                ConnectionPointer = Integer.parseInt(line[number].readLine());
                 System.out.println("current message: "+message +" at "+ConnectionPointer);
                if(message.equals(null)){
                    System.out.println("messsaageees equals to nulll");
                    return;
                }
                if(message.equals("downloadfile")){
                    message=null;
                    System.out.println("getting the files information.");

                    fileChooser();
                    long filesize;

                    filesize = file.length();

                    file_info = line[number].readLine();// the choosen file
                    lineout[number].println("downloadfile");

                    System.out.println("Sending downloadfile signal");

                     System.out.println("file_info = "+file_info);

                    System.out.println("sending real file info = "+file_info);
                    lineout[number].println(file.getName()+","+filesize+","
                               +client[number].getLocalPort()+","+ConnectionPointer);
                   // lineout[number].println("downloadfile");
                    //lineout[number].println("dlconfirmed");


                  System.out.println("running clientFileDownload class..");
                  new Thread(new clientFileDownload()).start();
                }
                else if(message.equals("uploadFile")){

                    System.out.println("sendfile message");
                    download=true;
                    System.out.println("waiting for file_info..");
                    file_info = line[number].readLine();
                    System.out.println("running acceptFile class..");
                    new Thread(new clientFileUpload()).start();
                    while(download=true){
                        }
                    System.out.println("Client upload complete");

                }


                    // if value of ConnectionPointer = 0,
                    // to print messages in lobby room
                ConnectionPointer=0; // print all messagges for the mean time
                if(ConnectionPointer==0){

                    int sendall=1;

                    while(sendall<connection){

                         System.out.println("sending message, sendingTo= "
                        + sendall +" connection "+ number);

                        lineout[sendall].println(message);
                        sendall++;
                        }
                    }
                else{
                        System.out.println("sending to someone else..");
                        //lineout[ConnectionPointer].println(message);
                       // lineout[0].println(message);// tempo
                        return;
                }

    			}
    		}
    		catch (Exception e){
    			System.out.println("ClientHandler error: "+e);
    		}
    	}
    }
      public void setupServer() {
        System.out.println("setting up server..");
        char  NetSelectNocharAt, inet='n';
        String ipadd=null;
        try {
            Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();

            if(inetaddress==null){
                for(int x=0;e.hasMoreElements()&&x<=100;x++){

                NetworkInterface n = e.nextElement();

                Enumeration<InetAddress> ee = n.getInetAddresses();
                while (ee.hasMoreElements()){

                    inetaddress = ee.nextElement();
                    System.out.println("InetAddress = "+inetaddress );

                    message =  inetaddress.getHostAddress().toString();

                    if(inet==('9')){
                        System.out.println("char - 9");
                        ipadd  =  JOptionPane.showInputDialog(frame,"Create server via: ",message);
                            server = new ServerSocket(3333,1,inetaddress);
                        }

                    // detects if ip 10.x.x.x
                    if(inet==('0')){

                        System.out.println("char - 0");
                        message = JOptionPane.showInputDialog(frame,"Create server via: ",message);

                        System.out.println("defualt logsts " + inetaddress);
                        int choice = JOptionPane.showConfirmDialog(frame,"Run Server via?: " + '\n' + inetaddress);

                        if(choice==0){

                           // inetaddress.getByName(inetadd);
                            System.out.println("confirmed");
                            break;
                            }
                        System.out.println("Scanning...");

                    }
                }
            }

            System.out.println("inetaddress "+inetaddress);

            }
         server = new ServerSocket(3333,1,inetaddress);
         System.out.println("server ok");
        }
         catch(IOException ex) {
            System.out.println("Establishing Server Error: " + ex+'\n');
        }
    }
     public void fileChooser(){
        try{
            filechoose = new JFileChooser();
            System.out.println("choosing a file..");
            int retrnValue = filechoose.showOpenDialog(null);
            if (retrnValue == JFileChooser.APPROVE_OPTION) {
                file = filechoose.getSelectedFile();
            }
        }
        catch(Exception e){
            System.out.println("2 Sending File Error: "+e);
        }
     }
    public  class clientFileUpload implements Runnable {

        public void run(){
              try{
                System.out.println("accepting file...");
                int filesize;
                int bytesRead;
                int currentTot = 0;
                String filename;
				int port = 0;
                String fileInformation = file_info;
                stringtokenizer = new StringTokenizer(fileInformation.trim(),",");
                System.out.println("file info: " + fileInformation);

                filename = stringtokenizer.nextToken();
                System.out.println("getting filename: " + filename);

                filesize = Integer.parseInt(stringtokenizer.nextToken());

                ConnectionPointer = Integer.parseInt(stringtokenizer.nextToken());
                port = Integer.parseInt(stringtokenizer.nextToken());

                port = 1233; // for the mean time only..

                ServerSocket fileserver = new ServerSocket(port);
                System.out.println("waiting for client filesocket..");
                Socket filesocket = fileserver.accept();

                System.out.println("userConnectionPointer: "+ConnectionPointer);


                System.out.println("file socket " + filesocket);

                filesize= filesize*2;
                byte [] bytearray  = new byte [filesize];
                InputStream is = filesocket.getInputStream();
                FileOutputStream fos = new FileOutputStream(filename);
                BufferedOutputStream bos = new BufferedOutputStream(fos);
                bytesRead = is.read(bytearray,0,bytearray.length);
                currentTot = bytesRead;
                System.out.println("reading input");
                do {
                   bytesRead =
                      is.read(bytearray, currentTot, (bytearray.length-currentTot));
                   if(bytesRead >= 0) currentTot += bytesRead;
                } while(bytesRead > -1);

                bos.write(bytearray, 0 , currentTot);
                bos.flush();
                bos.close();
                is.close();
              //  filesocket.close();

                System.out.println("client upload complete "+ filename);
                }
                catch (Exception e){
                   System.out.println("Accepting file error: "+ e);
                   download=false;
                }
            }
        }
    public class clientFileDownload implements Runnable{
        public void run(){
            try{
                System.out.println("running clientfiledownload class");
                String filename = file.getName();

                // get the desired file name first for client file downloading


                // use the client local port for file downloading if possible
                // port = socket.getLocalPort();
               int port = 2222; // temporary port  number

               System.out.println("getting the clients local port");


                ServerSocket downloadServerSocket = new ServerSocket(port);

                Socket clientDownloadSocket;

                // set a socket time out
                System.out.println("waiting for clients port..");
                // waits for client port to open
                clientDownloadSocket = downloadServerSocket.accept();

                System.out.println("Sending signal");
                // signals the client ready for file downloading..
              // lineout.println("uploadFile");
            //   lineout.println(ConnectionPointer);


                ConnectionPointer=0;//temporary


                byte [] bytearray  = new byte [(int)file.length()];

                FileInputStream fin = new FileInputStream(file);

                BufferedInputStream bin = new BufferedInputStream(fin);

                bin.read(bytearray,0,bytearray.length);
                OutputStream os = clientDownloadSocket.getOutputStream();
                System.out.println("Sending File...");
                os.write(bytearray,0,bytearray.length);
                os.flush();
                clientDownloadSocket.close();
                System.out.println("Clients File download complete");

            }
            catch (Exception e){
                System.out.println("clientDownload Error " + e);
            }
        }
    }
    public static void main(String[] args) {
        new Server();
    }
}
